use grpc_client::client::create_request::JobType;
use grpc_client::client::job_service_client::JobServiceClient;
use grpc_client::client::{BuildBlogParameter, CreateRequest, SyncDetailRequest, SyncLogRequest};
use std::time::Duration;
use std::{
    env, io,
    process::{Child, Command},
};
use tokio::time;
use tokio_stream::StreamExt;
use tonic::{Code, Status};

pub struct Daemon {
    child: Child,
}

impl Daemon {
    async fn new() -> io::Result<Daemon> {
        let bin = env::current_exe()?
            .parent()
            .and_then(|p| p.parent())
            .expect("Bin directory")
            .join("prtd")
            .to_path_buf();

        let mut cmd = Command::new(bin);
        let child = cmd.spawn()?;

        time::sleep(Duration::from_secs(5)).await;

        Ok(Self { child })
    }
}

impl Drop for Daemon {
    fn drop(&mut self) {
        self.child.kill().unwrap()
    }
}

#[tokio::test]
async fn build_blog_successfully() {
    let mut server = Daemon::new().await.unwrap();

    let mut client = JobServiceClient::connect("http://0.0.0.0:5000")
        .await
        .unwrap();

    let parameter = BuildBlogParameter {
        uri: "git@gitee.com:bear-god/toussaint_blog.git".to_string(),
        dst: "beargod@iceking.cc:docker/blog/html".to_string(),
    };
    let mut create = CreateRequest::default();
    create.job_type = Some(JobType::BuildBlog(parameter));
    let create_response = client.create(create).await.unwrap().into_inner();

    let job_id = create_response.info.unwrap().id;
    let mut sync_detail = SyncDetailRequest::default();
    sync_detail.id = job_id;
    let mut detail_stream = client.sync_detail(sync_detail).await.unwrap().into_inner();

    while let Some(detail_response) = detail_stream.next().await {
        let detail_response = detail_response.unwrap();

        let detail = detail_response.detail.unwrap();
        let info = detail.info.unwrap();
        println!("id: {}, state: {:?}", info.id, info.state());
    }
}
